import { Component, Input, Output, EventEmitter } from '@angular/core';
import { Page } from './pagination.model';

@Component({
    selector: 'sustainalytics-pagination',
    templateUrl: './pagination.component.html',
    styleUrls: ['./pagination.component.css']
})

export class PaginationComponent {
    //current page index
    private _pageIndex: number = 1;
    set pageIndex(value: number) {
        this._pageIndex = value;
        this.computeVisiblePages();
    }

    //number of elements per page
    private _pageSize: number = 20;
    get pageSize(): number { return this._pageSize; }
    set pageSize(value: number) {        
        this._pageSize = value;
        this._pageIndex = 1;
        this.computeTotalPageCount();              
        this.emitPagingOptionsChanged();
    }

    //total number of items
    public _totalItemsCount: number = 0;
    @Input('elemCount')
    set totalItemsCount(value: number) {
        if (value) {
            this._totalItemsCount = value;
            this.computeTotalPageCount();
        }
    }

    //total number of pages
    private _totalPageCount: number = 0;
    set totalPageCount(value: number){
        if(value){
            this._totalPageCount = value;
            this.computeVisiblePages();
        }
    }

    //number of pages visible for selection
    private visiblePages: number = 5;
    //page visibility start index
    private visiblePagesFrom: number = 1;
    //page visibility end index
    private visiblePagesTo: number = 1;
    //visibile pages
    private visiblePagesArray: number[];

    @Output() changed: EventEmitter<Page> = new EventEmitter();
 
    private prev() {
        if (this._pageIndex > 0) {
            // decrement page index
            this._pageIndex -= 1;
            // trigger changed event
            this.emitPagingOptionsChanged();
        }
    }

    private next() {
        if (this._pageIndex < this._totalPageCount) {
            // increment page index
            this._pageIndex += 1;
            // trigger changed event
            this.emitPagingOptionsChanged();
        }
    }

    private prevSet() {
        // keep old page index
        var oldPageIndex = this._pageIndex;

        // compute new page index
        var newPageIndex = this._pageIndex - this.visiblePages;

        // fix new page index
        if (newPageIndex < 1) {
            newPageIndex = 1;
        }

        // set new page index and trigger event
        if (oldPageIndex !== newPageIndex) {
            this.pageIndex = newPageIndex;
            this.emitPagingOptionsChanged();
        }
    }

    private nextSet() {
        // keep old page index
        var oldPageIndex = this._pageIndex;

        // compute new page index
        var newPageIndex = this._pageIndex + this.visiblePages;

        // fix new page index
        if (newPageIndex > this._totalPageCount) {
            newPageIndex = this._totalPageCount;
        }

        // set new page index and trigger event
        if (oldPageIndex !== newPageIndex) {
            this.pageIndex = newPageIndex;
            this.emitPagingOptionsChanged();
        }
    }

    public goTo(page: number) {
        // set page index
        this.pageIndex = page;

        // trigger changed event
        this.emitPagingOptionsChanged();
    }

    // number of items to take
    public takeCount(): number {
        return this._pageSize;
    }

    // number of items to skip
    public skipCount(): number {
        return (this._pageIndex - 1) * this._pageSize;
    }

    private computeTotalPageCount() {
        this.totalPageCount = Math.ceil(this._totalItemsCount / this._pageSize);
    }

    public computeVisiblePages() {
        var pageIndex = this._pageIndex;
        var visiblePages = this.visiblePages;
        var totalPageCount = this._totalPageCount;

        // compute how many pages to display before and after current page
        var prevPages = Math.floor(visiblePages / 2);
        var nextPages = visiblePages - 1 - prevPages;

        // compute visible pages range
        var from = pageIndex - prevPages;
        var to = pageIndex + nextPages;

        if (from < 1) {
            from = 1;
            to = visiblePages;
        }
        else {
            if (to > totalPageCount) {
                to = totalPageCount;
                from = totalPageCount - visiblePages + 1;
            }
        }

        // fix from inclusive
        if (from < 1) {
            from = 1;
        }

        // fix to inclusive
        if (to > this._totalPageCount)
            to = this._totalPageCount;

        // create the array of visible pages
        var visiblePagesArray = new Array();
        for (var index = from; index <= to; index++) {
            visiblePagesArray.push(index);
        }

        this.visiblePagesFrom = from;
        this.visiblePagesTo = to;
        this.visiblePagesArray = visiblePagesArray;
    }

    private emitPagingOptionsChanged() {        
        this.changed.emit(new Page(
            this.skipCount() > this._totalItemsCount ? this._totalItemsCount : this.skipCount(),
            this._pageSize
        ));
    }
}